package com.mxpio.erp.oa.service.impl;

import com.google.common.collect.Lists;
import com.mxpio.erp.common.enums.BizExceptionEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.model.request.BpmnSubmitRequest;
import com.mxpio.erp.common.oa.entity.HireApply;
import com.mxpio.erp.common.oa.service.HireApplyService;
import com.mxpio.erp.common.util.AssertUtil;
import com.mxpio.erp.common.util.CloneUtil;
import com.mxpio.erp.common.util.JacksonMapUtils;
import com.mxpioframework.camunda.service.BpmnFlowService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.PojoDictParseService;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

;

@Service
public class HireApplyServiceImpl extends BaseServiceImpl<HireApply> implements HireApplyService {

    @Resource
    private BpmnFlowService bpmnFlowService;

    @Resource
    private PojoDictParseService dictService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HireApply doSave(HireApply hireApply) {
        hireApply.setBpmnStatus(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode());
        this.save(hireApply);

        return hireApply;
    }

    @Override
    @Transactional
    public HireApply submit(BpmnSubmitRequest request) {

        AssertUtil.notEmpty(request.getBizNo(), BizExceptionEnums.PARAM_NOT_NULL, "bizNo");

        HireApply hireApplyOrder = this.getById(HireApply.class, request.getBizNo());

        AssertUtil.notNull(hireApplyOrder, BizExceptionEnums.ORDER_NOT_FOUND);

        //1. 开启工作流
        HireApply hireApply = parseDict(hireApplyOrder);
        Map<String, Object> workFlowParam = JacksonMapUtils.convertObjectToMap(hireApply);
        ProcessInstance processInstance = bpmnFlowService.startWithFormByKey(request.getKey(), SecurityUtils.getLoginUsername(), request.getBusinessKey(), workFlowParam);
        //2. 更新工单
        hireApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode());
        hireApplyOrder.setProcessInstanceId(processInstance.getId());
        this.update(hireApplyOrder);

        return hireApplyOrder;
    }

    @Override
    @Transactional
    public HireApply audit(BpmnSubmitRequest request) {

        AssertUtil.notEmpty(request.getBizNo(), BizExceptionEnums.PARAM_NOT_NULL, "bizNo");

        HireApply hireApplyOrder = this.getById(HireApply.class, request.getBizNo());

        AssertUtil.notNull(hireApplyOrder, BizExceptionEnums.ORDER_NOT_FOUND);

        List<String> passStatus = Lists.newArrayList(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode(),
                OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());

        AssertUtil.isTrue(passStatus.contains(request.getBpmnStatus()), BizExceptionEnums.ORDER_AUDIT_STATUS_ERROR);

        if (request.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())) {
            hireApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());
        } else {
            hireApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());
        }

        this.update(hireApplyOrder);

        return hireApplyOrder;
    }

    private HireApply parseDict(HireApply HireApplyOrder) {
        HireApply cloneHireApply = CloneUtil.deepClone(HireApplyOrder, HireApply.class);
        Result<HireApply> result = Result.OK(cloneHireApply);
        dictService.parseDictResult(result);
        return result.getResult();
    }
}